<?php
// +----------------------------------------------------------------------
// | FastXCMS [ WE CAN DO IT MORE SIMPLE ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2018 http://www.fastxcms.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 老猫 <thinkcmf@126.com>
// +----------------------------------------------------------------------
namespace app\portal\service;

use app\portal\model\PortalPostModel;
use app\portal\model\PortalCategoryModel;
use think\Db;

class ApiService
{
    /**
     * 功能:查询文章列表,支持分页;<br>
     * 注:此方法查询时关联两个表portal_category_post(category_post),portal_post(post);在指定排序(order),指定查询条件(where)最好指定一下表别名
     * @param array $param 查询参数<pre>
     * array(
     *  'category_ids'=>'',
     *  'where'=>'',
     *  'limit'=>'',
     *  'order'=>'',
     *  'page'=>'',
     *  'relation'=>''
     * )
     * 字段说明:
     * category_ids:文章所在分类,可指定一个或多个分类id,以英文逗号分隔,如1或1,2,3 默认值为全部
     * field:调用指定的字段@todo
     *   如只调用posts表里的id和post_title字段可以是post.id,post.post_title; 默认全部,
     *   此方法查询时关联两个表portal_category_post(category_post),portal_post(post);
     *   所以最好指定一下表名,以防字段冲突
     * limit:数据条数,默认值为10,可以指定从第几条开始,如3,8(表示共调用8条,从第3条开始)
     * order:排序方式,如按posts表里的published_time字段倒序排列：post.published_time desc
     * where:查询条件,字符串形式,和sql语句一样,请在事先做好安全过滤,最好使用第二个参数$where的数组形式进行过滤,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突,查询条件(只支持数组),格式和thinkPHP的where方法一样,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突;
     * </pre>
     * @return array 包括分页的文章列表<pre>
     * 格式:
     * array(
     *     "articles"=>array(),//文章列表,array
     *     "page"=>"",//生成的分页html,不分页则没有此项
     *     "total"=>100, //符合条件的文章总数,不分页则没有此项
     *     "total_pages"=>5 // 总页数,不分页则没有此项
     * )</pre>
     */
    public static function articles($param)
    {
		global $configinfo,$configbase;
		
		$topid    = empty($param['moduleID']) ? $configinfo['moduleid'] : $param['moduleID'];
		
        $portalPostModel = new PortalPostModel();
		// 新增自定义模块独立表配置 DATE:2020-3-27 START
		$moduletable = getmoduletable($topid);
		$moduletable = delthstr($moduletable,"fastxcms_","");
		$portalPostModel->name($moduletable);
		// 新增自定义模块独立表配置 DATE:2020-3-27 END

        $where = [
            'post.published_time' => [['> time', 0], ['<', time()]],
            'post.post_status'    => 1,
            'post.post_type'      => 1,
            'post.delete_time'    => 0
        ];
		// ----------------多语言配置START
		if($configinfo['langok'])
		{
			$where['post.lang'] = ['eq', $configinfo['lang']];
		}
		// ----------------多语言配置END

        $paramWhere = empty($param['where']) ? '' : $param['where'];
		$expWhere = empty($param['expwhere']) ? '' : $param['expwhere'];

        $limit       = empty($param['limit']) ? 10 : $param['limit'];
        $order       = empty($param['order']) ? 'is_top DESC,list_order DESC,post.published_time DESC' : $param['order'];
        $page        = isset($param['page']) ? $param['page'] : false;
        $relation    = empty($param['relation']) ? '' : $param['relation'];
        $categoryIds = empty($param['category_ids']) ? '' : $param['category_ids'];

        $join = [
			[['modulepara_para_list' => 'plist'], "post.id = plist.listid {$expWhere['orderwhere']}", "LEFT"],
			[['fastxcms_portal_category' => 'category'], 'post.category_id = category.id']
        ];
        
        // 配置读取字段
        $field = !empty($param['field']) ? $param['field'] : 'post.*,category.name as category_name';
        
        // 配置分类ID条件
        $categoryId = $categoryIds;
        $categoryIds = getbottomclass($configinfo["ecs_article_cat"],$categoryId,$configinfo['cat_id'],$configinfo['parent_id'],1);

        // 新增分类+扩展分类组合查询 DATE:2019-12-27 START
        $categoryWhere = "(post.category_id in (".$categoryIds.") OR concat(',',post.categories,',') like concat('%,',".$categoryId.",',%'))";// 通过concat进行字符组连接查询
        // 新增分类+扩展分类组合查询 DATE:2019-12-27 END
		
		// 商家操作数据权限
		if($expWhere['supplierok'] == 1)
		{
			$supplierwhere = getsupplierwhere(2,"post.");
			if($configinfo['supplier_id'])
			{
				$where+=$supplierwhere;	
			}
		}
		// 城市分站数据筛选
		if($expWhere['cityok'] == 1)
		{
			if(moduleaqvarval("countyid", "intval"))
			{
				$where['post.provinceid']=array('eq',moduleaqvarval("countyid", "intval"));
			}
			$cityid = moduleaqvarval("cityid", "intval") ? moduleaqvarval("cityid", "intval") : $configbase['cityid'];
			if($cityid)
			{
				$where['post.cityid']=array('eq',$cityid);
			}
			if(moduleaqvarval("countyid", "intval"))
			{
				$where['post.countyid']=array('eq',moduleaqvarval("countyid", "intval"));
			}
			if(moduleaqvarval("areaid", "intval"))
			{
				$where['post.areaid']=array('eq',moduleaqvarval("areaid", "intval"));
			}
		}

        $articles = $portalPostModel->alias('post')->field($field)
            ->join($join)
            ->where($where)
            ->where($categoryWhere)
            ->where($paramWhere)
			->where($expWhere['where'])
            ->order($order);
		
		// 排序时关联表不是通过主键递增的字段关联的不支持group id，plist表关联不是通过主键递增关联，所有这里排序plist的字段时不可设置group id
		// 也就是说group id使用时关联表必需通过主键递增的字段进行关联才可以使用
		if(empty($expWhere['orderwhere']))
		{
			$articles = $articles->group('post.id');	
		}

        $return = [];

        if (empty($page)) {
            $articles = $articles->limit($limit)->select();

            if (!empty($relation) && !empty($articles['items'])) {
                $articles->load($relation);
            }

            $return['articles'] = $articles;
        } else {

            if (is_array($page)) {
                if (empty($page['list_rows'])) {
                    $page['list_rows'] = 10;
                }

                $articles = $articles->paginate($page);
            } else {
                $articles = $articles->paginate(intval($page));
            }

            if (!empty($relation) && !empty($articles['items'])) {
                $articles->load($relation);
            }

            $articles->appends(request()->get());
            $articles->appends(request()->post());

            $return['articles']    = $articles->items();
            $return['page']        = $articles->render();
            $return['total']       = $articles->total();
            $return['total_pages'] = $articles->lastPage();
        }
		
		// 获取模块公用开启配置
		$topmodule_moduleconfig = gettopmodule($configinfo['moduleid'],"moduleconfig");
		
		foreach($return['articles'] as $key=>$val)
		{
			$parameterinfo = getmoduleparameter($val['id'], $val['module']);
			if($parameterinfo)
			{
				foreach($parameterinfo as $kp=>$vp)
				{
					$return['articles'][$key][$kp] = $vp;	
				}
			}
			// TAG标签列表
			if($val['post_keywords'] && $topmodule_moduleconfig['tagok'] == 1)
			{
				$taglist = getstrtoarr(",",$val['post_keywords']);
				$taglistarr = array();
				foreach($taglist as $k=>$v)
				{
					// 新增自定义模块独立表配置 DATE:2020-3-27 START
					$moduletable = getmoduletagtable($topid);
					// 新增自定义模块独立表配置 DATE:2020-3-27 END
					$taginfo = datainfo($moduletable,$v,"name");
					if(is_array($taginfo))
					{
						$taglistarr[$k]['tag_id'] = $taginfo['id'];	
						$taglistarr[$k]['name'] = $taginfo['name'];	
					}
				}
				$return['articles'][$key]['taglist'] = $taglistarr;
			}
		}

        return $return;

    }

    /**
     * 功能:查询标签文章列表,支持分页;<br>
     * 注:此方法查询时关联两个表portal_tag_post(tag_post),portal_post(post);在指定排序(order),指定查询条件(where)最好指定一下表别名
     * @param array $param 查询参数<pre>
     * array(
     *  'tag_id'=>'',
     *  'where'=>'',
     *  'limit'=>'',
     *  'order'=>'',
     *  'page'=>'',
     *  'relation'=>''
     * )
     * 字段说明:
     * field:调用指定的字段@todo
     *   如只调用posts表里的id和post_title字段可以是post.id,post.post_title; 默认全部,
     *   此方法查询时关联两个表portal_tag_post(category_post),portal_post(post);
     *   所以最好指定一下表名,以防字段冲突
     * limit:数据条数,默认值为10,可以指定从第几条开始,如3,8(表示共调用8条,从第3条开始)
     * order:排序方式,如按posts表里的published_time字段倒序排列：post.published_time desc
     * where:查询条件,字符串形式,和sql语句一样,请在事先做好安全过滤,最好使用第二个参数$where的数组形式进行过滤,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突,查询条件(只支持数组),格式和thinkPHP的where方法一样,此方法查询时关联多个表,所以最好指定一下表名,以防字段冲突;
     * </pre>
     * @return array 包括分页的文章列表<pre>
     * 格式:
     * array(
     *     "articles"=>array(),//文章列表,array
     *     "page"=>"",//生成的分页html,不分页则没有此项
     *     "total"=>100, //符合条件的文章总数,不分页则没有此项
     *     "total_pages"=>5 // 总页数,不分页则没有此项
     * )</pre>
     */
    public static function tagArticles($param)
    {
		global $configinfo;
		
		$topid    = empty($param['moduleID']) ? $configinfo['moduleid'] : $param['moduleID'];
		
        $portalPostModel = new PortalPostModel();
		// 新增自定义模块独立表配置 DATE:2020-3-27 START
		$moduletable = getmoduletable($topid);
		$moduletable = delthstr($moduletable,"fastxcms_","");
		$portalPostModel->name($moduletable);
		// 新增自定义模块独立表配置 DATE:2020-3-27 END

        $where = [
            'post.published_time' => [['> time', 0], ['<', time()]],
            'post.post_status'    => 1,
            'post.post_type'      => 1,
            'post.delete_time'    => 0
        ];

        $paramWhere = empty($param['where']) ? '' : $param['where'];

        $limit    = empty($param['limit']) ? 10 : $param['limit'];
        $order    = empty($param['order']) ? 'is_top DESC,list_order DESC,post.published_time DESC' : $param['order'];
        $page     = isset($param['page']) ? $param['page'] : false;
        $relation = empty($param['relation']) ? '' : $param['relation'];
		$categoryIds = empty($param['category_ids']) ? '' : $param['category_ids'];
        $tagId    = empty($param['tag_id']) ? '' : $param['tag_id'];

        $join = [
            //['__USER__ user', 'post.user_id = user.id'],
			[['fastxcms_portal_category' => 'category'], 'post.category_id = category.id']
        ];

        if (empty($tagId)) {
            return null;

        } else {
            
            // 配置读取字段
            $field = !empty($param['field']) ? $param['field'] : 'post.*,category.name as category_name';
			
            // 配置分类ID条件
			$categoryIds = getbottomclass($configinfo["ecs_article_cat"],$categoryIds,$configinfo['cat_id'],$configinfo['parent_id'],1);
            $where['post.category_id'] = ['in', $categoryIds];
            
			// 新增自定义模块独立表配置 DATE:2020-3-27 START
			$moduletable = getmoduletagtable($topid);
			// 新增自定义模块独立表配置 DATE:2020-3-27 END
			$taginfo = datainfo($moduletable,$tagId,"id");
			$where['post.post_keywords'] = ['like', '%'.$taginfo['name'].'%'];
        }

        $articles = $portalPostModel->alias('post')->field($field)
            ->join($join)
            ->where($where)
            ->where($paramWhere)
            ->order($order);

        $return = [];

        if (empty($page)) {
            $articles = $articles->limit($limit)->select();

            if (!empty($relation) && !empty($articles['items'])) {
                $articles->load($relation);
            }

            $return['articles'] = $articles;
        } else {

            if (is_array($page)) {
                if (empty($page['list_rows'])) {
                    $page['list_rows'] = 10;
                }

                $articles = $articles->paginate($page);
            } else {
                $articles = $articles->paginate(intval($page));
            }

            if (!empty($relation) && !empty($articles['items'])) {
                $articles->load($relation);
            }

            $articles->appends(request()->get());
            $articles->appends(request()->post());

            $return['articles']    = $articles->items();
            $return['page']        = $articles->render();
            $return['total']       = $articles->total();
            $return['total_pages'] = $articles->lastPage();
        }
		
		foreach($return['articles'] as $key=>$val)
		{
			$parameterinfo = getmoduleparameter($val['id']);
			if($parameterinfo)
			{
				foreach($parameterinfo as $kp=>$vp)
				{
					$return['articles'][$key][$kp] = $vp;	
				}
			}
			// TAG标签列表
			if($val['post_keywords'])
			{
				$taglist = getstrtoarr(",",$val['post_keywords']);
				$taglistarr = array();
				foreach($taglist as $k=>$v)
				{
					// 新增自定义模块独立表配置 DATE:2020-3-27 START
					$moduletable = getmoduletagtable($topid);
					// 新增自定义模块独立表配置 DATE:2020-3-27 END
					$taginfo = datainfo($moduletable,$v,"name");
					if(is_array($taginfo))
					{
						$taglistarr[$k]['tag_id'] = $taginfo['id'];	
						$taglistarr[$k]['name'] = $taginfo['name'];	
					}
				}
				$return['articles'][$key]['taglist'] = $taglistarr;
			}
		}

        return $return;
    }

    /**
     * 获取指定id的文章
     * @param int $id
     * @return array|false|\PDOStatement|string|\think\Model
     */
    public static function article($id, $topid=0)
    {
		global $configinfo;
		
		$topid    = empty($topid) ? $configinfo['moduleid'] : $topid;
		
        $portalPostModel = new PortalPostModel();
		// 新增自定义模块独立表配置 DATE:2020-3-27 START
		$moduletable = getmoduletable($topid);
		$moduletable = delthstr($moduletable,"fastxcms_","");
		$portalPostModel->name($moduletable);
		// 新增自定义模块独立表配置 DATE:2020-3-27 END

        $where = [
            'published_time' => [['> time', 0], ['<', time()]],
            'post_status'    => 1,
            'post_type'      => 1,
            'id'             => $id,
            'delete_time'    => 0
        ];

        return $portalPostModel->where($where)->find();
    }

    /**
     * 获取指定条件的页面列表
     * @param array $param 查询参数<pre>
     * array(
     *  'where'=>'',
     *  'order'=>'',
     * )</pre>
     * @return false|\PDOStatement|string|\think\Collection
     */
    public static function pages($param)
    {
        $paramWhere = empty($param['where']) ? '' : $param['where'];

        $order = empty($param['order']) ? '' : $param['order'];

        $portalPostModel = new PortalPostModel();

        $where = [
            'published_time' => [['> time', 0], ['<', time()]],
            'post_status'    => 1,
            'post_type'      => 2, //页面
            'delete_time'    => 0
        ];

        return $portalPostModel
            ->where($where)
            ->where($paramWhere)
            ->order($order)
            ->select();
    }

    /**
     * 获取指定id的页面
     * @param int $id 页面的id
     * @return array|false|\PDOStatement|string|\think\Model 返回符合条件的页面
     */
    public static function page($id)
    {
        $portalPostModel = new PortalPostModel();

        $where = [
            'published_time' => [['> time', 0], ['<', time()]],
            'post_status'    => 1,
            'post_type'      => 2,
            'id'             => $id,
            'delete_time'    => 0
        ];

        return $portalPostModel->where($where)->find();
    }

    /**
     * 返回指定分类
     * @param int $id 分类id
     * @return array 返回符合条件的分类
     */
    public static function category($id)
    {
		global $configinfo;
		
        $portalCategoryModel = new PortalCategoryModel();

        $where = [
            'status'      => 1,
            'delete_time' => 0,
            'id'          => $id
        ];
		
		$category = $portalCategoryModel->where($where)->find();
		
		// 获取语言关联栏目信息
		if($configinfo['columnattrok'] == 1 && $configinfo['langok'] == 1)
		{
			foreach($categorys as $key=>$val)
			{
				$categorys[$key] = modulelangcolumn($val,$val['id']);
			}
		}

        return $category;
    }

	/**
	 * 返回指定分类下的子分类
	 * @param int $categoryId 分类id
	 * @param $field string  指定查询字段
	 * @throws \think\db\exception\DataNotFoundException
	 * @throws \think\db\exception\ModelNotFoundException
	 * @throws \think\exception\DbException
	 * @return false|\PDOStatement|string|\think\Collection 返回指定分类下的子分类
	 */
	public static function subCategories($param)
	{
		global $configinfo;
		
		$portalCategoryModel = new PortalCategoryModel();
		
		$paramWhere = empty($param['where']) ? '' : $param['where'];

        $order = empty($param['order']) ? 'list_order ASC,id ASC' : $param['order'];

		$where = [
			'status'      => 1,
			'delete_time' => 0,
			'parent_id'   => $param['categoryId']
		];
		
		$categorys = $portalCategoryModel->field($field)->where($where)->where($paramWhere)->order($order)->select();
		
		// 获取语言关联栏目信息
		if($configinfo['columnattrok'] == 1 && $configinfo['langok'] == 1)
		{
			foreach($categorys as $key=>$val)
			{
				$categorys[$key] = modulelangcolumn($val,$val['id']);
			}
		}

		return $categorys;
	}

    /**
     * 返回指定分类下的所有子分类
     * @param int $categoryId 分类id
     * @return array 返回指定分类下的所有子分类
     */
    public static function allSubCategories($param)
    {
		global $configinfo;
		
        $portalCategoryModel = new PortalCategoryModel();
		
		$paramWhere = empty($param['where']) ? '' : $param['where'];

        $order = empty($param['order']) ? 'list_order ASC,id ASC' : $param['order'];

        $categoryId = intval($param['categoryId']);

        if ($categoryId !== 0) {
            $category = $portalCategoryModel->field('path')->where('id', $categoryId)->find();

            if (empty($category)) {
                return [];
            }

            $categoryPath = $category['path'];
        } else {
            $categoryPath = 0;
        }

        $where = [
            'status'      => 1,
            'delete_time' => 0,
            'path'        => ['like', "$categoryPath-%"]
        ];
		
		$categorys = $portalCategoryModel->where($where)->where($paramWhere)->order($order)->select();
		
		// 获取语言关联栏目信息
		if($configinfo['columnattrok'] == 1 && $configinfo['langok'] == 1)
		{
			foreach($categorys as $key=>$val)
			{
				$categorys[$key] = modulelangcolumn($val,$val['id']);
			}
		}

		return $categorys;
    }

    /**
     * 返回符合条件的所有分类
     * @param array $param 查询参数<pre>
     * array(
     *  'where'=>'',
     *  'order'=>'',
     * )</pre>
     * @return false|\PDOStatement|string|\think\Collection
     */
    public static function categories($param)
    {
		global $configinfo;
		
        $paramWhere = empty($param['where']) ? '' : $param['where'];

        $order = empty($param['order']) ? 'list_order ASC,id ASC' : $param['order'];

        $portalCategoryModel = new PortalCategoryModel();

        $where = [
            'status'      => 1,
            'delete_time' => 0,
        ];
		
		$categorys = $portalCategoryModel->where($where)->where($paramWhere)->order($order)->select();
			
		// 获取语言关联栏目信息
		if($configinfo['columnattrok'] == 1 && $configinfo['langok'] == 1)
		{
			foreach($categorys as $key=>$val)
			{
				$categorys[$key] = modulelangcolumn($val,$val['id']);
			}
		}

        return $categorys;
    }

    /**
     * 获取面包屑数据
     * @param int $categoryId 当前文章所在分类,或者当前分类的id
     * @param boolean $withCurrent 是否获取当前分类
     * @return array 面包屑数据
     */
    public static function breadcrumb($categoryId, $withCurrent = false)
    {
		global $configinfo;
		
        $data                = [];
        $portalCategoryModel = new PortalCategoryModel();

        $path = $portalCategoryModel->where(['id' => $categoryId])->value('path');

        if (!empty($path)) {
            $parents = explode('-', $path);
            if (!$withCurrent) {
                array_pop($parents);
            }

            if (!empty($parents)) {
                $data = $portalCategoryModel->where(['id' => ['in', $parents]])->order('path ASC')->select();
            }
        }
		
		// 获取语言关联栏目信息
		if($configinfo['columnattrok'] == 1 && $configinfo['langok'] == 1)
		{
			foreach($data as $key=>$val)
			{
				$data[$key] = modulelangcolumn($val,$val['id']);
			}
		}

        return $data;
    }

}